package com.leinao.login.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.leinao.commons.Response;
import com.leinao.config.EnvironmentConfig;
import com.leinao.config.RedisCacheConfig;
import com.leinao.constant.Constant;
import com.leinao.constant.LoginEnum;
import com.leinao.login.dto.LoginResultDto;
import com.leinao.login.service.LoginService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;

/**
 * @author wangshoufa
 * @date 2018年11月15日 下午12:01:53
 *
 */
@Service
public class LoginServiceImpl implements LoginService {

	Logger logger = LoggerFactory.getLogger(LoginServiceImpl.class);

	@Autowired
	EnvironmentConfig env;

	@Autowired
	private RestTemplate restTemplate;

	@Autowired
	private RedisCacheConfig redisCacheConfig;


    /**
     * 功能描述：登录方法
     * @param request req请求
     * @param username 用户名 一般是邮箱
     * @param password 密码
     * @return com.leinao.commons.Response<java.lang.Object> 返回登录结果
     * @Author: guoliangbo
     * @Date: 2019/4/22 14:47
     */
	@Override
	public Response<Object> login(HttpServletRequest request, String username, String password) {
		HttpSession session = request.getSession();
		Integer expireSeconds = env.getExpireSeconds();
		logger.debug("redis expireSeconds: {}", expireSeconds);
		MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
		map.add("username", username);
		map.add("password", password);
		map.add("expiration", String.valueOf(expireSeconds));
		String resBody = null;
		try {
			resBody = restTemplate.postForObject(env.getRestServerUrl() + Constant.REST_SERVER_LOGIN_API, map, String.class);
			if (StringUtils.isNotBlank(resBody)) {
				JSONObject pobj = JSON.parseObject(resBody);
				Integer code = (Integer) pobj.get("code");
				if (code == Constant.LOGIN_RESULT_SUCCESS) {
					LoginResultDto result = JSON.parseObject(resBody, LoginResultDto.class);
					if(!result.getDeveloper()) {
						return Response.ok( Constant.RESPONSE_STATUS_SUCCESS, LoginEnum.USER_NOT_DEVELOPER.getSeq(), LoginEnum.USER_NOT_DEVELOPER.getDesc(), result.getUserId());
					}
					BigDecimal validityTime = result.getValidateTime();
					logger.debug("bitaToken validityTime: {}", validityTime);
					// 取小者
					if (validityTime.compareTo(new BigDecimal(expireSeconds)) < 0) {
						// 取整
						logger.debug("validityTime s: {}", validityTime.setScale(0, BigDecimal.ROUND_DOWN));
						expireSeconds = Integer.valueOf(String.valueOf(validityTime.setScale(0, BigDecimal.ROUND_DOWN)));
					}
					logger.debug("last redis expireSeconds: {}", expireSeconds);
					// 以秒为单位
					if (expireSeconds.compareTo(0) > 0) {
						session.setMaxInactiveInterval(expireSeconds);
					}
					// 数据放入redis 缓存中
					String bitaKey = env.getPrefix() + result.getBitaToken();
					String paiKey = env.getPrefix() + result.getToken();
					Jedis jedis = null;
					try {
						JedisPool jedisPool = redisCacheConfig.getJedisPool();
						jedis = jedisPool.getResource();
						String bitaResu = jedis.get(bitaKey);
						String paiResu = jedis.get(paiKey);
						if (StringUtils.isBlank(bitaResu) || StringUtils.isBlank(paiResu)) {
							// 数据不为空 放入缓存
							logger.debug("to redis bita key: {}", bitaKey);
							logger.debug("to redis pai key: {}", paiKey);
							jedis.setex(bitaKey, expireSeconds, JSON.toJSONString(result));
							jedis.setex(paiKey, expireSeconds, JSON.toJSONString(result));
						}
						session.setAttribute("userInfo", JSON.toJSONString(result));
					} catch (Exception e) {
						logger.warn("Login Warning");
						logger.error("get redisResource failed loginResult to redis failed");
						logger.error(e.getMessage(), e);
					} finally {
						if (jedis != null) {
							jedis.close();
						}
						logger.debug("data into redis over");
					}
					return Response.error(Constant.RESPONSE_STATUS_SUCCESS, LoginEnum.LOGIN_SUCCESS.getSeq(), LoginEnum.LOGIN_SUCCESS.getDesc(),
							result);
				}
				if (code == Constant.LOGIN_RESULT_USER_NOT_EXIST ) {
					return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, LoginEnum.USER_NOT_EXIST.getSeq(), LoginEnum.USER_NOT_EXIST.getDesc(),
							null);
				}
				if (code == Constant.LOGIN_RESULT_PASSWORD_ERROR) {
					return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, LoginEnum.PASSWORD_ERROR.getSeq(), LoginEnum.PASSWORD_ERROR.getDesc(),
							null);
				} else {
					return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, code, (String) pobj.get("message"), null);
				}
			}
		} catch (Exception e) {
			logger.error(String.format("request login auth failed"));
			logger.error(e.getMessage(), e);
			return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, LoginEnum.LOGIN_FAILED.getSeq(), LoginEnum.LOGIN_FAILED.getDesc(), null);
		}
		return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, LoginEnum.LOGIN_FAILED.getSeq(), LoginEnum.LOGIN_FAILED.getDesc(), null);
	}

}
